جزوه · فصل نهم · جلسه ۸۴ · گرفتن متغیر از کاربر ← بازگشت به فهرست
📘 فصل نهم · جلسه ۸۴ گرفتن متغیر از کاربر
📅 تاریخ: چهارشنبه، ۳ شهریور ۱۴۰۵ 👤 مدرس: محمد عابدینی 🐚 Zsh · 🐧 Debian (کالی) · 📦 Red Hat
این جلسه یکی از مباحث کلیدی برای تعامل با کاربر در اسکریپت‌ها است. دستور read و گزینه‌های آن (مانند -p، -s، -t) حتماً در آزمون‌های عملی مطرح می‌شوند.
🤖 قبل از شروع، یه مثال ساده:

فرض کن یه دستگاه خودپرداز داری که از کاربر می‌خواد رمز و مبلغ رو وارد کنه. توی لینوکس، دستور read دقیقاً همینه: به اسکریپت شما اجازه می‌ده از کاربر ورودی بگیره و توی متغیرها ذخیره کنه. این جلسه بهت یاد میده چطور با read اسکریپت‌های تعاملی (Interactive) بنویسی!

▍ دستور read چیست؟

read یک دستور داخلی در Bash است که ورودی کاربر را از صفحه‌کلید (یا یک فایل) می‌خواند و در یک یا چند متغیر ذخیره می‌کند. این دستور اساس ساخت اسکریپت‌های تعاملی است.

🔑 نکته کلیدی: read اجرای اسکریپت را متوقف می‌کند و منتظر می‌ماند تا کاربر متنی را وارد کند و Enter را بزند. سپس متن وارد شده را در متغیر(های) مشخص‌شده ذخیره می‌کند.

• ساده‌ترین شکل استفاده

#!/bin/bash # گرفتن یک متغیر از کاربر echo "لطفاً نام خود را وارد کنید:" read name echo "سلام $name! خوش آمدی."
┌──(ya3in㉿kali)-[~] └─$ ./ask_name.sh لطفاً نام خود را وارد کنید: Ali سلام Ali! خوش آمدی.

توضیح: اسکریپت یک پیام چاپ می‌کند، سپس با read name منتظر می‌ماند تا کاربر نامش را تایپ کند. بعد از فشردن Enter، مقدار در متغیر name ذخیره شده و در خط بعد چاپ می‌شود.

اگر به read هیچ متغیری ندهید، ورودی در متغیر پیش‌فرض REPLY ذخیره می‌شود.

▍ گزینه‌های مفید read

گزینه کاربرد مثال
-p "prompt" نمایش پیام (پرامپت) قبل از دریافت ورودی read -p "نام: " name
-s ورودی را مخفی می‌کند (مناسب برای رمز عبور) read -s -p "رمز: " pass
-t seconds زمان انتظار (Timeout) به ثانیه read -t 5 -p "نام: " name
-n N پس از دریافت N کاراکتر، بدون نیاز به Enter ادامه بده read -n 1 -p "ادامه؟ (y/n) " ans
-a array ورودی را به صورت آرایه ذخیره می‌کند read -a colors
-d delimiter تعیین جداکنندهٔ پایان ورودی (به جای Enter) read -d ':' name

• استفاده از -p (نمایش پیام)

گزینهٔ -p به شما اجازه می‌دهد که پیام راهنما را در همان خط قبل از ورودی نمایش دهید و نیازی به echo جداگانه نباشد. این روش ظاهر حرفه‌ای‌تر و کد کوتاه‌تر ایجاد می‌کند.

#!/bin/bash # استفاده از -p برای نمایش پیام همراه با ورودی read -p "لطفاً سن خود را وارد کنید: " age days=$[ $age * 365 ] echo "شما بیش از $days روز سن دارید!"
┌──(ya3in㉿kali)-[~] └─$ ./age_calc.sh لطفاً سن خود را وارد کنید: 25 شما بیش از 9125 روز سن دارید!

توضیح: -p پیام را نمایش می‌دهد، سپس ورودی را می‌گیرد و در age ذخیره می‌کند. سپس محاسبهٔ روزها انجام شده و چاپ می‌شود.

• استفاده از -t (زمان انتظار / Timeout)

گزینهٔ -t به شما امکان می‌دهد مدت زمان مشخصی (به ثانیه) برای دریافت ورودی تعیین کنید. اگر کاربر در آن مدت چیزی وارد نکند، read با کد خروجی غیرصفر پایان می‌یابد و اسکریپت می‌تواند ادامه دهد. این قابلیت برای مدیریت زمان در برنامه‌های تعاملی بسیار مفید است.

#!/bin/bash # تنظیم Timeout با -t if read -t 5 -p "لطفاً نام خود را وارد کنید (۵ ثانیه): " name; then echo "سلام $name، به اسکریپت من خوش آمدی." else echo "متأسفیم، زمان شما تمام شد!" fi
┌──(ya3in㉿kali)-[~] └─$ ./timeout_example.sh لطفاً نام خود را وارد کنید (۵ ثانیه): (اگر چیزی وارد نشود، بعد از ۵ ثانیه) متأسفیم، زمان شما تمام شد!

توضیح: اگر کاربر ظرف ۵ ثانیه نام خود را وارد کند، پیام خوش‌آمدگویی چاپ می‌شود. در غیر این صورت پیام «زمان تمام شد» نمایش داده می‌شود.

نکته امتحانی: read -t در صورت timeout، کد خروجی غیرصفر برمی‌گرداند که با if قابل بررسی است.

• استفاده از -s (ورودی مخفی)

گزینهٔ -s (Silent) باعث می‌شود که آنچه کاربر تایپ می‌کند در ترمینال نمایش داده نشود. این ویژگی برای دریافت رمز عبور یا اطلاعات حساس کاربرد دارد.

#!/bin/bash # گرفتن رمز عبور به صورت مخفی read -s -p "رمز عبور خود را وارد کنید: " password echo echo "رمز عبور شما با موفقیت ذخیره شد."
┌──(ya3in㉿kali)-[~] └─$ ./secret.sh رمز عبور خود را وارد کنید: (هیچ چیزی نمایش داده نمی‌شود) رمز عبور شما با موفقیت ذخیره شد.

توضیح: با -s تایپ کاربر در صفحه نمایش داده نمی‌شود. بعد از read معمولاً یک echo خالی می‌گذاریم تا خط جدیدی ایجاد شود و پیام بعدی در خط بعدی چاپ شود.

نکته: -s فقط ورودی را مخفی می‌کند، اما خود متغیر مقدار را در خود نگه می‌دارد. برای امنیت بیشتر، بهتر است رمز را پس از استفاده پاک کنید.

• ترکیب گزینه‌ها

می‌توانید چند گزینه را با هم ترکیب کنید، مثلاً -s و -t و -p با هم:

#!/bin/bash # ترکیب -s (مخفی) و -t (زمان‌دار) if read -t 10 -s -p "رمز یکبارمصرف (۱۰ ثانیه): " token; then echo echo "رمز تأیید شد." else echo echo "زمان مجاز به پایان رسید." fi

▍ خواندن چندین متغیر با یک read

می‌توانید با یک read چندین متغیر را پر کنید. ورودی را با فاصله یا تب جدا کنید.

#!/bin/bash # گرفتن نام و نام‌خانوادگی read -p "نام و نام‌خانوادگی: " first last echo "نام: $first، نام‌خانوادگی: $last"
┌──(ya3in㉿kali)-[~] └─$ ./fullname.sh نام و نام‌خانوادگی: Ali Rezaei نام: Ali، نام‌خانوادگی: Rezaei

توضیح: اولین کلمه (Ali) در $first و دومین کلمه (Rezaei) در $last ذخیره می‌شود. اگر تعداد کلمات بیشتر از متغیرها باشد، بقیه در آخرین متغیر ریخته می‌شود.

اگر تعداد متغیرهای read از تعداد کلمات ورودی بیشتر باشد، متغیرهای اضافی خالی می‌مانند.

▍ جمع‌بندی و نکات مهم

✅ جمع‌بندی نهایی:
  • read → دستور اصلی برای دریافت ورودی از کاربر.
  • -p → نمایش پیام قبل از ورودی (جایگزین echo).
  • -s → مخفی کردن ورودی (برای رمزها و اطلاعات حساس).
  • -t → تعیین زمان انتظار (Timeout) بر حسب ثانیه.
  • -n → تعداد کاراکترهای مورد نیاز برای پایان ورودی (بدون Enter).
  • چند متغیره: با یک read می‌توانید چندین متغیر را با فاصله پر کنید.
  • ترکیب: می‌توانید گزینه‌ها را با هم ترکیب کنید (مثلاً -s -t).
📝 تمرین پیشنهادی:

یک اسکریپت بنویسید که:

  • از کاربر با read -p نام و سن را بگیرد.
  • اگر کاربر چیزی وارد نکرد (متغیر خالی بود)، پیام «ورودی نامعتبر» چاپ کند.
  • در غیر این صورت، پیام خوش‌آمدگویی مناسب با سن کاربر چاپ کند.
  • برای رمز عبور از -s استفاده کنید و یک timeout ۵ ثانیه‌ای نیز تنظیم کنید.